using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace ApplicationLibrary.ExtendedControls
{
    /// <summary>
    /// Summary description for AquaButton.
    /// </summary>
    [Serializable]
    public class MenuButton : System.Windows.Forms.Button
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        private bool mouseOver = false;
        private bool mouseClick = false;
        public Color toColor = Color.LightBlue;

        [Category("Appearance"),
        Description("Fade Color")]
        public Color ToColor
        {
            get { return toColor; }
            set { toColor = value; }
        }

        ///
        ///Additional variables to handle pulsing
        ///
        private ImageAttributes imgAttr = new ImageAttributes();

        public MenuButton()
        {
            // This call is required by the Windows.Forms Form Designer.
            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                ControlStyles.DoubleBuffer |
                ControlStyles.UserPaint, true);
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            components = new System.ComponentModel.Container();
        }

        #endregion

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            Color col = this.Parent.BackColor;
            g.Clear(this.Parent.BackColor);
            Color clr = this.BackColor;
            Rectangle rc = new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height);
            LinearGradientBrush br1;
            ColorBlend colorBlend = new ColorBlend(2);
            colorBlend.Colors = new Color[] { toColor, toColor, clr };
            colorBlend.Positions = new float[] { 0F, 0.5F, 1F };

            if (mouseOver && mouseClick)
                br1 = new LinearGradientBrush(new Point(0, 0), new Point(0, rc.Height), clr, toColor);
            else
                br1 = new LinearGradientBrush(new Point(0, rc.Height), new Point(0, -3), clr, toColor);

            br1.InterpolationColors = colorBlend;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            GraphicsPath path1 = this.GetPath(rc, 10);
            g.FillPath(br1, path1); //draw main
            Pen pen1 = new Pen(SystemColors.ControlDark);
            g.DrawPath(pen1, path1);

            ///Set the region for the button
            Region rgn = new Region(path1);
            rgn.Union(path1);
            this.Region = rgn;

            float x = 0, y = 0;
            int bW = this.Bounds.Width;
            int bH = this.Bounds.Height;
            if (this.Image != null)
            {
                ImageAttributes ia = new ImageAttributes();
                int imgW = this.Image.Width < bW ? this.Image.Width : bW;
                int imgH = this.Image.Height < bH ? this.Image.Height : bH;
                Rectangle rect = new Rectangle(0, 0, imgW, imgH);

                if (this.ImageAlign == ContentAlignment.BottomLeft ||
                    this.ImageAlign == ContentAlignment.MiddleLeft ||
                    this.ImageAlign == ContentAlignment.TopLeft)
                    x = 3;

                if (this.ImageAlign == ContentAlignment.BottomCenter ||
                    this.ImageAlign == ContentAlignment.MiddleCenter ||
                    this.ImageAlign == ContentAlignment.TopCenter)
                    x = (imgW < bW) ? (bW - imgW) / 2 + 2 : 0;

                if (this.ImageAlign == ContentAlignment.BottomRight ||
                    this.ImageAlign == ContentAlignment.MiddleRight ||
                    this.ImageAlign == ContentAlignment.TopRight)
                    x = (imgW < bW) ? (bW - imgW - 3) : 0;

                if (this.ImageAlign == ContentAlignment.BottomLeft ||
                    this.ImageAlign == ContentAlignment.BottomCenter ||
                    this.ImageAlign == ContentAlignment.BottomRight)
                    y = (imgH < bH) ? (bH - imgH) : 0;

                if (this.ImageAlign == ContentAlignment.MiddleCenter ||
                    this.ImageAlign == ContentAlignment.MiddleLeft ||
                    this.ImageAlign == ContentAlignment.MiddleRight)
                    y = (imgH < bH) ? (bH - imgH) / 2 + 2 : 0;

                if (this.ImageAlign == ContentAlignment.TopCenter ||
                    this.ImageAlign == ContentAlignment.TopLeft ||
                    this.ImageAlign == ContentAlignment.TopRight)
                    y = 0;

                ia.SetColorKey(Color.FromArgb(255, 0, 255), Color.FromArgb(255, 0, 255));
                try
                {
                    g.DrawImage(this.Image, x, y, imgW, imgH);
                }
                catch (Exception exc)
                {
                    string msg = exc.Message;
                }
            }

            SolidBrush brush = new SolidBrush(this.ForeColor);
            SizeF sizef = g.MeasureString(this.Text, this.Font);
            if (this.TextAlign == ContentAlignment.BottomLeft ||
                this.TextAlign == ContentAlignment.MiddleLeft ||
                this.TextAlign == ContentAlignment.TopLeft)
                x = 0;

            if (this.TextAlign == ContentAlignment.BottomCenter ||
                this.TextAlign == ContentAlignment.MiddleCenter ||
                this.TextAlign == ContentAlignment.TopCenter)
                x = (sizef.Width < bW) ? (bW - sizef.Width) / 2 : 0;

            if (this.TextAlign == ContentAlignment.BottomRight ||
                this.TextAlign == ContentAlignment.MiddleRight ||
                this.TextAlign == ContentAlignment.TopRight)
                x = (sizef.Width < bW) ? (bW - sizef.Width) : 0;

            if (this.TextAlign == ContentAlignment.BottomLeft ||
                this.TextAlign == ContentAlignment.BottomCenter ||
                this.TextAlign == ContentAlignment.BottomRight)
                y = (sizef.Height < bH) ? (bH - sizef.Height) : 0;

            if (this.TextAlign == ContentAlignment.MiddleCenter ||
                this.TextAlign == ContentAlignment.MiddleLeft ||
                this.TextAlign == ContentAlignment.MiddleRight)
                y = (sizef.Height < bH) ? (bH - sizef.Height) / 2 : 0;

            if (this.TextAlign == ContentAlignment.TopCenter ||
                this.TextAlign == ContentAlignment.TopLeft ||
                this.TextAlign == ContentAlignment.TopRight)
                y = 0;

            g.DrawString(this.Text, this.Font, brush, x, y);
        }

        private GraphicsPath GetPath(Rectangle rc, int r)
        {
            int x = rc.X, y = rc.Y, w = rc.Width, h = rc.Height;
            GraphicsPath path = new GraphicsPath();
            path.AddArc(x, y, r, r, 180, 90);				//Upper left corner
            path.AddArc(x + w - r, y, r, r, 270, 90);			//Upper right corner
            path.AddLine(x + w, y + h, x, y + h);
            path.AddLine(x, y + h, x, y);
            return path;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseClick = true;
                this.Invalidate();
            }
            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            mouseClick = false;
            this.Invalidate();
            base.OnMouseUp(e);
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            mouseOver = true;
            this.Cursor = Cursors.Hand;
            this.Invalidate();
            base.OnMouseEnter(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            mouseOver = false;
            this.Cursor = Cursors.Default;
            this.Invalidate();
            base.OnMouseLeave(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            //mouseOver = this.Bounds.Contains(e.X, e.Y);
            //Debug.WriteLine(mouseOver.ToString());

            base.OnMouseHover(e);
        }

        //-----------------------------------------------------------------
        // METHODS TO HANDLE PULSING
        //-----------------------------------------------------------------

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            this.Invalidate();  //redraw to get back it's original picture
        }
    }
}